#ifndef _JS_H_
#define _JS_H_

//#define XP_UNIX 1

//#define DEBUG 1

#include <js/jsapi.h>
#include <prio.h> 
#include <prthread.h> 

#if JS_VERSION <= 180
# define JS_AddNamedValueRoot  JS_AddNamedRoot
# define JS_AddNamedObjectRoot JS_AddNamedRoot
# define JS_RemoveValueRoot    JS_RemoveRoot
# define JS_RemoveObjectRoot   JS_RemoveRoot
#endif


extern JSRuntime *rt;
extern JSContext *gcx;


//char *stoa(JSContext *cx, jsval s);
//jsval atos(JSContext *cx, char *a);
//char *get_prop(JSContext *cx, jsval v, const char *propname);



#define TEXT_NOTOBJECT "NOT OBJECT"
#define TEXT_UNDEFINED "undefined"


//char TEXT_NOTOBJECT[]="NOT OBJECT";
//char TEXT_UNDEFINED[]="undefined";


JSContext *create_context(JSContext *);
void destroy_context(JSContext *);

void execute(void(*proc)(void *), void *arg, int async);

JSObject *get_global_object();

char *json_encode(JSContext *cx, jsval x);
JSBool json_decode(JSContext *cx, char *str, jsval *rval);


JSBool c2jsarray(JSContext *cx, uintN len, char **argv, jsval *rval);


const char *geta(JSContext *cx, JSObject *ar, int n, const char *def);

int geti(JSContext *cx, JSObject *ar, int index, int _default);

char *vtoa(JSContext *cx, jsval s);

jsval atov(JSContext *cx, const char *a);


const char *get_prop(JSContext *cx, jsval v, const char *propname);


JSBool c2jsarray(JSContext *cx, uintN len, char **argv, jsval *rval);


void reportError(JSContext *cx, const char *message, JSErrorReport *report);

JSContext *js_init();

//void js_done(int ret);


char * _js_convert_arg_to_str(JSContext *, jsval *, int);
long _js_convert_arg_to_long(JSContext *, jsval *, int);
long _js_convert_arg_to_int(JSContext *, jsval *, int);



#define ARG_STR(n)  _js_convert_arg_to_str(cx, vp, n)
#define ARG_LONG(n) _js_convert_arg_to_long(cx, vp, n)
#define ARG_INT(n)  _js_convert_arg_to_int(cx, vp, n)

#define ERR(...) { JS_ReportError(cx, __VA_ARGS__); return JS_FALSE; }



//extern JSObject  *global;
//extern JSContext  *global_cx;
//extern pthread_mutex_t mux;
//extern pthread_t httpserver_thread;

extern char **cmd_argv;
extern int cmd_argc;


//void js_init();

//int eval(char *code, const char *filename, int lineno);
//int eval_file(char *);

//int eval_file(char *);

#define DECLATE_CONSTRUCTOR(x) \
static JSBool x (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);


#define IMPLEMENT_CONSTRUCTOR(x) \
static JSBool x(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){\
	struct T *x = calloc(sizeof(struct T), 1);\
	JS_SetPrivate(cx, obj, x);\
	return JS_TRUE;\
}



#endif /* _JS_H_ */

